<?php
/*------------------------------------------------------------------------------
this file is part of Web Application Kit http://webappkit.net
Copyright (C) 2006 J.Ducastel <fredbird@fredbird.org>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
------------------------------------------------------------------------------*/

/**
* ordered pile data construct
* manages references, not copies
* allows ordering
* @author J.Ducastel <fredbird@fredbird.org>
* @version 
*/
class wakPile {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	*
	* @access
	*/
	function wakPile($order='asc') {
		$this->__construct($order);
	}/**/
	
	/**
	* "real" constructor
	* @access
	*/
	function __construct($order='asc') {
		$this->setOrder($order);
	}/**/
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* inserts a new item
	* @param mixed &$item
	* @param int $position optional
	* @access public
	* @return bool
	*/
	function insert(& $item, $position=null) {
		if (is_int($position))
			$this->data[$position][]=&$item;
		else
			$this->data[][]=&$item;
		$this->sort();
		return true;
	}/**/
	
	/**
	* returns next item
	* @param
	* @access public
	* @return mixed
	*/
	function & shift() {
		// getting the first position sub-array
		//echo "<p>going to shift an item from pile, ".count($this->data).' positions left</p>';
		reset($this->data);
		$position=key($this->data);
		$sub=current($this->data);
		if (!isset($this->data[$position])) {
			$item=null;
			array_shift($this->data);
		} else {
			// shifting item from sub
			$item=array_shift($this->data[$position]);
			// shifting position from main array if empty
			if (!$this->data[$position]) {
				array_shift($this->data);
			}
		}
		//echo '<p>got '.wakdebug::vardump($item).'</p>';
		return $item;
		/*switch ($this->order) {
			case 'asc': // down->top
				$pos=reset($this->data);
				// shifting position if empty
				//if (!$pos)
				//array_shift($this->data);
				break;
			case 'desc':
				$pos=end($this->data);
				// shifting position if empty
				//array_pop($this->data);
				break;
		}
		if ($pos)
			$item=&array_shift($pos);
		else
			// we are at the end of data
			$item=null;*/
		return $item;
	}/**/
	
	/**
	* Sets pile order
	* @param string $order asc|desc
	* @access public
	* @return bool
	*/
	function setOrder($order) {
		switch ($order) {
			case 'asc':
			case 'desc':
				$this->order=$order;
				$this->sort();
				return true;
			default:
				return false;
		}
	}/**/
	
	/**
	* 
	* @param
	* @access public
	* @return bool
	*/
	function isEmpty() {
		return count($this->data)>0;
	}/**/
	
	/**
	* returns pile's data as an array
	* @param
	* @access public
	* @return array
	*/
	function dump() {
		$data=array();
		foreach ($this->data as $sub)
			foreach ($sub as $item)
				$data[]=$item;
		return $data;
	}/**/
	
	/**
	* empites pile
	* @param
	* @access public
	* @return bool
	*/
	function clear() {
		$this->data=array();
		return true;
	}/**/
	
	/**
	* return a copy of next item 
	* @param
	* @access public
	* @return mixed
	* /
	function getNext() {

	}/**/
	
	/**
	* 
	* @param
	* @access public
	* @return 
	* /
	function () {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                      properties
------------------------------------------------------------------------------*/
	/**
	* @var type desc
	*/
	var $data=array(); // [position][n] items
	var $order='asc'; // asc|desc ascendant, descendant
	// var $
/*------------------------------------------------------------------------------
                                                               protected methods
------------------------------------------------------------------------------*/
	/**
	* 
	* @param
	* @access protected
	* @return 
	* /
	function () {
		
	}/**/
	
	/**
	* 
	* @param
	* @access protected
	* @return 
	* /
	function () {
		
	}/**/
	
/*------------------------------------------------------------------------------
                                                                 private methods
------------------------------------------------------------------------------*/
	/**
	* returns next element for the pile
	* @param
	* @access private
	* @return mixed
	* /
	function & getNext() {
		switch ($this->order) {
			case 'asc':
				$pos=reset($data);
				break;
			case 'desc':
				$pos=end($this->data);
				break;
		}
		$item=&array_shift($pos);
		return $item;
	}/**/
	
	/**
	* 
	* @param
	* @access private
	* @return 
	* /
	function & shiftPosition($position) {
		
	}/**/
	
	/**
	* sorts pile upon order
	* @param
	* @access private
	* @return 
	*/
	function sort() {
		switch ($this->order) {
			case 'asc':
				ksort($this->data);
				break;
			case 'desc':
				krsort($this->data);
				break;
			default:
				return false;
		}
		return true;
	}/**/
	
	/**
	* 
	* @param
	* @access private
	* @return 
	* /
	function () {
		
	}/**/
}
?>
